home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
vol_100
/
113_01
/
a15get.c
< prev
next >
Wrap
Text File
|
1985-03-09
|
9KB
|
325 lines
/*
HEADER: CUG113;
TITLE: 1802 Cross-Assembler (BDS C Version);
FILENAME: A15GET.C;
VERSION: 1.2;
DATE: 07/22/1985;
DESCRIPTION: "This program lets you use your CP/M-80-based computer
to assemble code for the RCA 1802, 1804, 1805, 1805A,
1806, AND 1806A microprocessors. The program is
written in BDS C for the best possible performance on
8-bit machines. All assembler features are supported
except relocation, linkage, listing control, and
macros.";
KEYWORDS: Software Development, Assemblers, Cross-Assemblers,
RCA, CDP1802, CDP1805A;
SEE-ALSO: CUG149, 1805A Cross-Assembler (Portable);
SYSTEM: CP/M-80;
COMPILERS: BDS C;
WARNINGS: "This package is specifically tailored to CP/M-80
machines and the rather non-standard, but high-
performance BDS C compiler. For other environments,
use the portable version of this package on CUG149.";
AUTHORS: William C. Colley III;
*/
/*
1805A Cross-Assembler v 1.2
Copyright (c) 1980, 82, 83, 85 William C. Colley, III.
July 1982 -- Adapted from my 1802 cross-assembler. WCC3.
Vers 1.0 -- March 1983 -- Added 1805A opcodes to the 1805 set. WCC3.
Vers 1.1 -- March 1983 -- Added CPU pseudo-op to combine 1802 and 1805A
cross-assemblers into a single program. WCC3.
Vers 1.2 -- June 1985 -- Fixed IF block nesting mechanism bug and bug
in 1805A SCAL opcode. WCC3.
File: a15get.c
Routines to get source text from the disk and return it in
manageable chunks such as operators, labels, opcodes, etc.
*/
/* Get Globals: */
#include "a15.h"
/*
Function to get an opcode from the present source line and return its value
and attributes. The function returns -1 if no opcode was on the line, 0 if
the opcode was not in the opcode table, and 1 otherwise. If the opcode was
on the line, but not in the table, the error is marked up.
*/
getopcod(value,attrib)
char *value, *attrib;
{
char temp[SYMLEN+1], getopc(), getchr();
switch (getchr(value,SKIP)) {
case ALPHA: backchr; getname(temp);
if (bsearch(temp,value,attrib,0,numopcs(),getopc) &&
(extend || (*attrib & (PSOP | XOPC)) != XOPC))
return 1;
markerr('O'); return 0;
default: markerr('S'); return -1;
case END_LIN: return -1;
}
}
/*
Function to look up an item in a fixed table by binary search. The function
returns 1 if the item was found, 0 if not. name points to the name to be
looked up (null terminated). value and attrib catch two bytes of parameters
attached to the item if the item is found. high and low are for the benefit of
the recursion. For the first call use the number of items in the table for
high and 0 for low. table is a pointer to a function to get an item from the
appropriate table. Note that in the comparison, lower case is converted to
upper case.
*/
bsearch(name,value,attrib,low,high,table)
char *name, *value, *attrib, (*table)();
int low, high;
{
char temp[5], *pntr1, *pntr2;
int t, check;
if (low > high) return 0;
check = low + (high - low >> 1); (*table)(check,temp,value,attrib);
pntr1 = temp; pntr2 = name;
while ((t = toupper(*pntr2++) - *pntr1) == 0 && *pntr1++ != '\0');
if (t) return t > 0 ? bsearch(name,value,attrib,check+1,high,table) :
bsearch(name,value,attrib,low,check-1,table);
return 1;
}
/*
Function to push back an item so that getitem will retrieve it a second time.
Only one level of pushback is supported.
*/
backitem(value,attrib)
unsigned value, attrib;
{
oldvalu = value; oldattr = attrib; backflg = TRUE;
}
/*
Function to get an item from the present source line. Items may be
looked-up symbols, numeric constants, string constants, operators, etc.
The function returns the attribute of the item gotten. value is a
pointer to where the value of the item will be stored, and quoteflg
determines whether getitem will look for one- and two-character string
constants or not.
*/
getitem(value,quoteflg)
unsigned *value;
char quoteflg;
{
char c, c1, attrib, *tmpptr, temp[2*SYMLEN];
unsigned base;
if (backflg) { backflg = FALSE; *value = oldvalu; return oldattr; }
switch ((attrib = getchr(&c,SKIP))) {
case END_LIN:
case COMMA: return attrib;
case NUMERIC: backchr; getnum(value,&base); return VALUE;
case OPERATR: switch (c) {
case '>':
case '=':
case '<': getchr(&c1,NOSKIP);
if (c == '>' && c1 == '=') c = GRTEQ;
else if (c == '>' && c1 == '<') c = NOTEQ;
else if (c == '=' && c1 == '>') c = GRTEQ;
else if (c == '=' && c1 == '<') c = LESEQ;
else if (c == '<' && c1 == '>') c = GRTEQ;
else if (c == '<' && c1 == '=') c = LESEQ;
else backchr;
default: *value = c; return attrib;
}
case QUOTE: if (quoteflg) { *value = c; return attrib; }
tmpptr = temp; attrib = 0;
while ((getchr(&c1,NOSKIP),c1) != '\n' && c1 != c)
if (++attrib <= 2) *tmpptr++ = c1;
if (c1 == '\n' || attrib > 2) {
if (c1 == '\n') backchr;
evalerr = TRUE; markerr('"'); return VALUE;
}
tmpptr = temp;
for (*value = 0; attrib != 0; attrib--)
*value = (*value << 8) + *tmpptr++;
return VALUE;
case ALPHA: backchr; getname(temp);
if (strcmp(temp,"$") == 0) {
*value = pc; return VALUE;
}
if ((*value = chkoprat(temp) & 0xff) != NO_OPR)
return OPERATR;
strcat(temp,PADDING);
if (slookup(temp) == 0) {
*value = sympoint -> symvalu;
if (sympoint -> symname[0] > 0x7f)
directok = FALSE;
}
else { evalerr = TRUE; markerr('U'); }
return VALUE;
}
}
/*
Function to get a symbol name, opcode, or label from the present source
line. The name is returned (null terminated) in buffer. Names are
terminated by any non-alphanumeric character.
*/
getname(buffer)
char *buffer;
{
char c, d, count;
count = 0;
while ((c = getchr(&d,NOSKIP)) == ALPHA || c == NUMERIC)
if (++count <= SYMLEN) *buffer++ = d;
backchr; *buffer = '\0';
}
/*
Function to check a string against the list of operators that get spelled out.
This list consists of GE, GT, LE, LT, EQ, NE, AND, OR, XOR, NOT, MOD, SHL,
SHR, HIGH, LOW. The function returns the token for the operator if the
string is an operator, the token NO_OPR otherwise.
*/
chkoprat(string)
char *string;
{
char s, t, getopr();
return (bsearch(string,&s,&t,0,numoprs(),getopr)) ? t : NO_OPR;
}
/*
Function to get an Intel format number from the present input line.
value points to the number to be returned, and base points to an
unsigned where the base of the number will be saved during internal
computations. The function returns a fixed value of 1 and flags errors
as it goes along.
*/
getnum(number,base)
unsigned *number, *base;
{
char c1, c2, toupper();
unsigned b;
if ((c1 = getchr(&c2,NOSKIP)) != ALPHA && c1 != NUMERIC) {
backchr; return 0xffff;
}
if ((b = getnum(number,base)) == 0xffff) {
*number = 0;
switch (toupper(c2)) {
case 'H': *base = 16; return 1;
case 'D': *base = 10; return 1;
case 'O':
case 'Q': *base = 8; return 1;
case 'B': *base = 2; return 1;
default: *base = 10; b = 1;
}
}
*number += b * _aton(toupper(c2),*base);
return b * *base;
}
/*
Internal function in getnum to convert a character to a digit. The base
is passed so that this routine can check for digits larger than the base.
*/
_aton(letter,base)
char letter;
unsigned base;
{
unsigned n;
if (letter >= '0' && letter <= '9') n = letter - '0';
else if (letter >= 'A' && letter <= 'F') n = letter - ('A' - 10);
else { markerr('E'); evalerr = TRUE; return 0; }
if (n < base) return n;
markerr('D'); evalerr = TRUE; return 0;
}
/*
Function to get a character from the present source line. The function
returns the attribute of the character fetched. value is a pointer to
the location where the character itself will be saved, and skipflg
deter